/*
 * Solution.h
 *
 *  Created on: 17/05/2011
 *      Author: daniel
 */

#ifndef SOLUTION_H_
#define SOLUTION_H_

#include <vector>
#include "Node.h"

using namespace std;

class Solution {

public:
	double **C;
	int cityNumber;
	int *tour;
	double cost;

	// Datos de reporte.
	double iniCost;
	int numIter;

	/**
	 * Construye una solucion vacia.
	 */
	Solution();

	/**
	 * @param: Numero de ciudades.
	 */
	Solution(int n);

	/**
	 * @param: Numero y lista de ciudades.
	 */
	Solution(int n, vector<Node> Ciudades);

	/**
	 * Retorna la posicion en tour de la ciudad siguiente
	 * a la ciudad i.
	 * @param: int posicion.
	 */
	int next(int pos);

	/**
	 * Retorna la posicion en tour de la ciudad
	 * anterior a la ciudad i.
	 */
	int prev(int pos);

	/**
	 * Busca la mejor solucion entre los vecinos
	 * que no este en la Lista Tabu (LT), a menos
	 * que la solucion sea mejor que la mejor
	 * encontrada hasta el momento
	 * @param: Lista de vecinos.
	 * 		   Lista TABU (LT).
	 * 		   Mejor Solucion encontrada
	 *         hasta el momento (sMejor).
	 * @return: Mejor solucion.
	 */
	int** bestSolution(vector<int> neighbors, Solution* sMejor, int **LT, int LTsize);


	/**
	 * Retorna un diferencial de costo.
	 * @param: Dos posiciones en el arreglo.
	 * @return: Un double que significa el costo diferencial.
	 */
	double costDifferential(int a, int b);

	/**
	 * Recalcula el costo de la solucion.
	 * @return: El costo recalculado.
	 */
	double recomputeCost();


	/**
	 * Agrega una nueva ciudad al tour (vacio).
	 * @param: la ciudad.
	 */
	int addCity(int city);

	/**
	 * Intercambia el contenido de las posiciones
	 * a y b.
	 * @param: int a, int b.
	 */
	Solution *swap(int a, int b);

	/**
	 * Intercambia dos arcos del camino.
	 * @param: dos enteros no consecutivos, correspondientes
	 * 		   a la ciudad inicial de los arcos que se quieren
	 * 		   intercambiar.
	 */
	Solution *flip(int a, int c);

   /**
	* Retorna el costo de ir de a a b.
	* @param: la posicion de la ciudad a y la de
	* 		  la ciudad b.
	*/
	double getCost(int a, int b);

	/**
	 * Retorna el costo de ir de la ciudad a a la b.
	 * @param: la ciudad a y la ciudad b.
	 */
	double getCostByCity(int a, int b);

	/**
	 * Actualiza el costo de la solucion.
	 */
	void updateCost(int a, int b);

	/**
	 * Copia la solucion.
	 * @return: Una nueva solucion.
	 */
	Solution *clone();

	/**
	 * Imprime la solucion.
	 */
	void print();

	/**
	 * Imprime por pantalla con formato.
	 */
	void printWithFormat();

	/**
	 * Escribe la solucion a un archivo.
	 */
	void write(char* fileName);

	void reverse(int inicial, int final);

	Solution* reverseWay(int inicial, int final);

	int** updateLT(int min, int max, int size, int **LT, int ltsize);

	int** bestSolution(vector<int> neighbors, Solution* sMejor, int **LT);

	virtual ~Solution();
};

#endif /* SOLUTION_H_ */
